/*
 * Javlov - a Java toolkit for reinforcement learning with multi-agent support.
 * 
 * Copyright (c) 2009 Matthijs Snel
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package net.javlov;

import java.io.Serializable;

/**
 * Represents the state of an agent, i.e. its current perception of the environment. For most
 * problems, states will be vectors of numbers, so it is convenient to use the VectorState class.
 *
 * @author Matthijs Snel
 * @version 0.2, 16/05/2009
 * @see VectorState
 */
public class State<T> implements Cloneable, Serializable {
	
	private static final long serialVersionUID = -6859111001292978754L;
	private static int counter = 0;
	
	private int id;
	
	protected T data;
	protected boolean terminal;
	
	public State() {
		this( null, false );
	}
	
	public State( T data ) {
		this(data, false);
	}
	
	public State( T data, boolean terminal ) {
		id = counter++;
		this.data = data;
		this.terminal = terminal;
	}
	
	public T getData() {
		return data;
	}
	
	public int getID() {
		return id;
	}
	
	public boolean isTerminal() {
		return terminal;
	}
	
	public void setTerminal(boolean terminal) {
		this.terminal = terminal;
	}
	
	/// OBJECT OVERRIDES
	/**
	 * Returns a shallow copy of this State, i.e. the data contained in the State is not copied.
	 * 
	 * @return a shallow copy of this State
	 */
	@Override
	@SuppressWarnings("unchecked")
	public Object clone() {
		State<T> s = null;
		try {
			s = (State<T>) super.clone();
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
		}
		return s;
	}
	
	@Override
	@SuppressWarnings("unchecked")
	public boolean equals( Object o ) {
		if ( o == null || !(o instanceof State) )
			return false;
		State s = (State) o;
		return (terminal == s.terminal) && data.equals(s.data);
	}
	
	@Override
	public int hashCode() {
		return 31*data.hashCode() + (terminal ? 1 : 0);
	}
}